package cn.csg.iotplatform.module.system.service.permission;


import cn.csg.iotplatform.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.csg.iotplatform.module.system.dal.dataobject.permission.MenuDO;
import cn.csg.iotplatform.module.system.dal.mysql.permission.MenuMapper;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;


@Component
@Slf4j
public class PermissionCheckService implements ApplicationContextAware {

    @Resource
    private MenuMapper menuMapper;

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public int checkPerimissions(Long parentId,String namePrefix,String oClassName) {
        int result = 0;
        final ConfigurableListableBeanFactory beanFactory = ((AnnotationConfigServletWebServerApplicationContext) applicationContext).getBeanFactory();
        for (String beanName : applicationContext.getBeanNamesForAnnotation(RestController.class)) {
            final String className = beanFactory.getBeanDefinition(beanName).getBeanClassName();
            try {
                if(!className.endsWith(oClassName)) continue;
                final Class<?> clazz = Class.forName(className);
                MenuDO parent = menuMapper.selectOne(MenuDO::getId,parentId);
                if(parent == null) continue;
                for (Method method : clazz.getMethods()) {
                    for (Annotation annotation : method.getDeclaredAnnotations()) {
                        if (annotation.annotationType() == PreAuthorize.class) {
                            final PreAuthorize preAuthorizes = (PreAuthorize) annotation;
                            String values = preAuthorizes.value();
                            values = values.substring("@ss.hasPermission".length() + 2,values.length() - 2);
                            String[] valueAttr = values.split(",");
                            for(String value : valueAttr){
                                updateMenu(parent,namePrefix,value,3);
                            }
                        }
                    }
                }
            } catch (Exception e) {
                log.error("checkPerimissions error ! beanName:{}", beanName);
            }
        }
        return result;
    }

    private void updateMenu(MenuDO parent,String namePrefix, String value,Integer type) {
        MenuDO child = new MenuDO();
        child.setParentId(parent.getId());
        child.setPermission(value);
        child.setStatus(0);
        child.setType(type);
        String[] values = value.split(":");
        switch (values[values.length-1]){
            case "create":
                child.setName(namePrefix+"新增");
                break;
            case "query":
                child.setName(namePrefix+"查询");
                break;
            case "delete":
                child.setName(namePrefix+"删除");
                break;
            case "update":
                child.setName(namePrefix+"更新");
                break;
            case "export":
                child.setName(namePrefix+"导出");
                break;
            case "import":
                child.setName(namePrefix+"导入");
                break;
            default:
                child.setName(value);
                break;
        }
        MenuDO menuDO = menuMapper.selectByParentIdAndName(child.getParentId(),child.getName());
        if(menuDO != null){
            BeanUtil.copyProperties(child,menuDO);
            menuMapper.updateById(menuDO);
        }else{
            menuMapper.insert(child);
        }
    }

}

